package com.example.activiti.service;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 用来展示审批过程的服务
 * @author zjh
 *
 */
@Service
public class ShowProcessService {
	@Autowired
	private RepositoryService repositoryService;
	@Autowired
	private TaskService taskService;
	/** 显示流程图
	 * @param request
	 * @param deploymentId 流程图的唯一编号
	 * @param instanceId 流程实例编号
	 * @throws UnsupportedEncodingException 
	 */
	public void displayFlowCurrPicnew(String deploymentId, String instanceId,HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException{
		if(StringUtils.isBlank(deploymentId)) {
			deploymentId = null;
		}
		String fileName = instanceId+".png";
		response.setHeader("content-type", "application/octet-stream");
		response.setHeader("Content-Disposition", "attachment;filename="+new String(fileName.getBytes("ISO-8859-1"), "UTF-8"));
		InputStream imageStream = null;
		OutputStream outputStream = null; 
	    try {
	        ProcessDefinition  processDefinition=repositoryService
	        		.createProcessDefinitionQuery()
	        		.deploymentId(deploymentId)//使用部署对象ID查询
	                .singleResult();
	        List<Task> activeTasks=taskService
	        		.createTaskQuery()
	        		.processDefinitionId(processDefinition.getId())
	        		.processInstanceId(instanceId)
	        		.list();
	        // 已执行的节点ID集合
	        List<String> executedActivityIdList = new ArrayList<String>();
	        List<String> highLines = new ArrayList<String>();
	        List<String> highNodes = new ArrayList<String>();

	        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
	        for(Task tk:activeTasks){
	            executedActivityIdList.add(tk.getTaskDefinitionKey());
	            highLines.addAll(getHighLines(bpmnModel,tk.getTaskDefinitionKey()));
	            highNodes.addAll(getHighNodes(bpmnModel,tk.getTaskDefinitionKey()));
	        }
	        // 获取流程图图像字符流
	        imageStream = new DefaultProcessDiagramGenerator().generateDiagram(bpmnModel, "png",
	                highNodes, highLines, "宋体", "宋体", "宋体", null, 1.0);
	        outputStream  = response.getOutputStream();
	        // 输出资源内容到相应对象
	        byte[] b = new byte[1024];
	        int len;
	        while ((len = imageStream.read(b, 0, 1024)) != -1) {
	        	outputStream.write(b, 0, len);
	        }
	    } catch (Exception e) {
	        e.printStackTrace();
	        if(outputStream!=null) {
	        	try {
					outputStream.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
	        }
	        if(imageStream!=null) {
	        	try {
					imageStream.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
	        }
	    }
	}
	/**
	 * 获取高亮的线
	 * @param bpmnModel
	 * @param key
	 * @return
	 */
	private Set<String> getHighLines(BpmnModel bpmnModel,String key){
	    FlowNode fl=(FlowNode) bpmnModel.getFlowElement(key);
	    List<SequenceFlow> pvmTransitions = fl.getIncomingFlows();
	    Set<String> highLines=new HashSet<>();
	    for(SequenceFlow sf:pvmTransitions){
	        highLines.add(sf.getId());
	        if(StringUtils.isNotBlank(sf.getSourceRef())){
	            highLines.addAll(getHighLines(bpmnModel,sf.getSourceRef()));
	        }
	    }
	    return highLines;
	}
	/**
	 * 获取高亮的节点
	 * @param bpmnModel
	 * @param key
	 * @return
	 */
	private Set<String> getHighNodes(BpmnModel bpmnModel,String key){
	    FlowNode fl=(FlowNode) bpmnModel.getFlowElement(key);
	    List<SequenceFlow> sequenceFlows = fl.getIncomingFlows();
	    Set<String> highNodes=new HashSet<>();
	    highNodes.add(key);
	    for(SequenceFlow sf:sequenceFlows){
	        if(StringUtils.isNotBlank(sf.getSourceRef())){
	            highNodes.addAll(getHighNodes(bpmnModel,sf.getSourceRef()));
	        }
	    }
	    return highNodes;
	}
}
